package com.sheep.jucdemo.part6.part6_2;

import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;

/**
 * @Date 2022/4/24 21:06
 * @Created by sheep
 */
public class Test6_2_3_2 {

    final static Test6_2_3_1 lock = new Test6_2_3_1();
    final static Condition notFull = lock.newCondition();
    final static Condition notEmpty = lock.newCondition();

    final static Queue<String> queue = new LinkedBlockingQueue<String>();
    final static int queueSize = 10;

    public static void main(String[] args) {

        Thread producer = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                System.out.println("producer加锁");
                try {
                    // (1)如果队列满了，则等待
                    while (queue.size() == queueSize) {
                        System.out.println("队列满，唤醒消费者");
                        notEmpty.await();
                    }

                    //（2）添加元素到队列
                    queue.add("ele");
                    System.out.println("producer放入元素");
                    //（3）唤醒消费队列
                    notFull.signalAll();
                    System.out.println("producer唤醒消费线程");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    // 释放锁
                    lock.unlock();
                    System.out.println("producer解锁");
                }
            }
        });
        Thread consumer = new Thread(new Runnable() {
            @Override
            public void run() {
                // 获取独占锁
                lock.lock();
                System.out.println("consumer加锁");
                try {
                    // 队列空，则等待
                    while (0 == queue.size()) {
                        System.out.println("队列为空，唤醒生产者");
                        notFull.await();

                    }
                    // 消费一个元素
                    String ele = queue.poll();
                    System.out.println("consumer取出元素");
                    // 唤醒生产线程
                    notEmpty.signalAll();
                    System.out.println("consumer唤醒生产线程");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    // 释放锁
                    lock.unlock();
                    System.out.println("consumer解锁");
                }
            }
        });
        // 启动线程
        consumer.start();
        producer.start();
    }

}
